package com.apestech.api.xml.esb.modul;

import com.apestech.api.condition.ConFieldM;
import com.apestech.api.xml.esb.EsbUtil;
import com.apestech.framework.dictionary.modul.Table;
import com.apestech.framework.json.JSON;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.util.StringUtil;
import com.apestech.framework.util.callback.SpiltStrCallback;
import com.apestech.framework.xml.plugin.modul.SysCondition;

import java.util.ArrayList;

public class EsbFormConditionField extends EsbFormPub {
//    private String type;
//    private String fkey;
//    private boolean noNull;
//    private boolean foreign;
//    private String theme;
//    private JSONObject fjson=null;
//    private JSONObject fieldJson;
//    private SysCondition sysCondition;

////////////////////////////////////
    private String id;
    private ConFieldM conFieldM;
    private Table.Field dfield;
    private String label;
    private String comment;
    private String oper;
    private JSONObject input;
    private boolean esb=false;
    private String rid;
    private JSONObject fieldJson;
    private JSONObject param=new JSONObject();

    private boolean notnull=false;
    private String formType="zd";

    /*
        bill_oper   //表单－制单 type=#{control_type} 联想和下拉字段都有对应配置
        bill_query  //表单－查询 type=conditionInput, config_type=#{control_type}, config-operators公式, 联想和下拉字段都有对应配置
        grid_oper   //表格－制单 type=cellEditor, 联想下拉允许编辑，需要配置
        grid_query  //表格－查询 type=cellEditor, cellEditor=input 静态允许查看，对应ID+NAME显示模式（ID）NAME
    }*/

    public EsbFormConditionField(String oper, String formType, ConFieldM conFieldM, String id, JSONObject input) throws Exception {
        this.oper=oper;
        this.conFieldM=conFieldM;
        this.id=id;
        this.formType=formType;
        rid=conFieldM.getRfield(id);
        if(rid==null){
            rid=id;
        }
        this.input=input;
        dfield=conFieldM.getDfield(id);
        comment=conFieldM.getRemark(id);
        if(id.equals("STATE")){
            if("zd".equals(formType)||"cx".equals(formType)){
                comment="状态(sent:新建;exec:执行;stop:终止)";
            } else if("imp".equals(formType)){
                comment="状态(sent:新建;exec:生成策略单号)";
                rid="IMP_STATE";
            } else if("stop".equals(formType)){
                comment="状态(sent:新建;exec:终止)";
                rid="STOP_STATE";
            }
        }
        label=getSpiltId(comment);
        fieldJson=conFieldM.getFieldD(id);
        if(fieldJson==null){
            fieldJson=new JSONObject();
        }
        notnull="true".equals(fieldJson.getString("required"));
    }

    /*
    1）初始化确认字段所在场景
    2）初始化是否有外部个性化定义
    3）初始化字段对应TYPE类型
    4）每种情况数据初始化，特殊->普通顺序
    */
    public JSONObject getField() throws Exception {
//        param.putAll(conFieldM.getFieldD(id));
//        param.put("field", id);
//        param.put("id", id);
        if("bill_query".equals(oper)){  //type=conditionInput  config_type=正常type
            param.put("type", "conditionInput");
            param.put("config_type","input");
        } else {
            param.put("type", "input");
        }
        if(!label.equals(comment) && comment.indexOf(";")>=0 && comment.indexOf(":")>=0){
            setDownList();
        } else if(conFieldM.isForkey(id)){
            setSelect();
        } else {
            setOther();
        }
        getFieldFini();
        return param;
    }

    private void setDownList() throws Exception {
        ArrayList<ArrayList<String>> mlist=null;
        String memo=comment;
        mlist = getStrSplitList("; :", getSplitList(memo));
        EsbUtil.setDownData(id, mlist);
        if(!oper.equals("bill_query")){
            param.put("type", "select");
        } else {
            param.put("config_type","select");
        }
        param.put("api","strategy.getDownData");
        param.put("init",true);

        if(conFieldM.getFieldD(id)!=null && conFieldM.getFieldD(id).get("downFormatter")!=null){
            param.put("downFormatter", conFieldM.getFieldD(id).get("downFormatter"));
        } else {
            param.put("downFormatter","'[' + value.id + ']' + value.name");
        }
        if(conFieldM.getFieldD(id)!=null && conFieldM.getFieldD(id).get("valueFormatter")!=null){
            param.put("valueFormatter", conFieldM.getFieldD(id).get("valueFormatter"));
        } else {
            param.put("valueFormatter","value? ('[' + value.id + ']' + value.name):''");
        }
        param.put("domain","('field', '=', '"+id+"')");
        param.put("cellRenderer","renderSelect");
        if(oper.indexOf("query")>=0 ||
                ("stop".equals(formType) && oper.indexOf("bill")>=0
                        && !id.equals("EXE_CONDITION") && !id.equals("EXE_DIMENSION")) ){
            if(!"djgc".equals(formType)){
                param.put("multiple","true");
            }
        }
        JSONObject in=new JSONObject();
        in.put("sysField", id);  //rid
        if(!esb){
            param.put("domain",JSON.toJSONString(in));
        } else {
            param.put("domain","[('sysField', '=', '"+id+"')]");  //rid
        }
        if(oper.equals("grid_query")){
//            StringBuffer s=new StringBuffer();
//            boolean f=true;
//            int mlen=mlist.size();
//            for(int m=0; m<mlen; m++){
//                String value=mlist.get(m).get(0);
//                String name=mlist.get(m).get(1);
//                if(!f) s.append("\r\n else ");
//                s.append("if (value === '"+value+"') { return '"+name+"'; }");
//                f=false;
//            }
//            if(!f) param.put("valueFormatter", s.toString());
        }
    }

    private void setSelect() throws Exception {
        JSONObject m= conFieldM.getMdef(id);
        if(m==null) throw new Exception("字段["+rid+"]没有配置，请补全！");
        String auxiliaryField=m.getString("auxiliaryField");
        if(auxiliaryField==null){
            auxiliaryField="";
        }
        int pos=auxiliaryField.indexOf(",");
        if(pos>=0){
            auxiliaryField=auxiliaryField.substring(0, pos).trim();
        }
        String mcField=auxiliaryField;
        if(mcField==null) mcField=id;

        if(!oper.equals("bill_query")){
            param.put("type", "select");
        } else {
            param.put("config_type","select");
        }

        String fk="ID";
        if(conFieldM.getImp(id)!=null){
            fk=conFieldM.getImp(id).getPkColumnName();
        }

        if(oper.indexOf("query")>=0 ||
                ("stop".equals(formType) && oper.indexOf("bill")>=0
                        && !id.equals("EXE_CONDITION") && !id.equals("EXE_DIMENSION")) ){
            if(!"djgc".equals(formType)){
                param.put("multiple","true");
                param.put("uniqueKey",fk);
                param.put("addSame",false);
            }
        }
        if(conFieldM.getFieldD(id)!=null && conFieldM.getFieldD(id).get("downFormatter")!=null){
            param.put("downFormatter", conFieldM.getFieldD(id).get("downFormatter"));
        } else {
            param.put("downFormatter","'[ ' + value."+fk+" + ' ]' + ' ' + value."+mcField);
        }
        if(conFieldM.getFieldD(id)!=null && conFieldM.getFieldD(id).get("valueFormatter")!=null){
            param.put("valueFormatter", conFieldM.getFieldD(id).get("valueFormatter"));
        } else {
            param.put("valueFormatter", "value? '[ ' + value." + fk + " + ' ]' + ' ' + value." + mcField + ":''");
        }
        JSONObject in=new JSONObject();
        in.put("sysField", rid);
        in.put("sysKey", "{{value}}");
        if(oper.indexOf("query")>0){
            in.put("sysPurpose", "pp_search");
        } else {
            in.put("sysPurpose", "pp_operate");
        }
        if(!esb){
            param.put("domain",JSON.toJSONString(getDomain(in)));
        } else {
            param.put("domain","['&','&', ('sysPurpose', '=', 'pp_operate'), ('sysKey', '=', '{{value}}'),('sysField', '=', '"+rid+"')]");
        }
        if(param.get("api")==null){
            param.put("api","pub.queryForm");
        }
        if(!id.equals("EXE_CONDITION") && !id.equals("EXE_DIMENSION")){
            param.put("searchFormId","strategy.field."+rid+"_"+formType);
            //param.put("required","true");
        }
        if(fieldJson!=null && fieldJson.get("width")!=null){
            param.put("width",fieldJson.getIntValue("width"));
        } else {
            param.put("width",300);
        }
        param.put("bindValue","ID");
    }

    private void setOther() throws Exception {
        String dbtype=null;
        if(dfield!=null){
            dbtype=dfield.getDbType();
        } else {
            dbtype=conFieldM.getFieldD(id).getString("type");
        }
        if(dbtype==null || dbtype.indexOf("CHAR")>=0){
            if(oper.equals("bill_query")){
                param.put("config_type", "string");
            } else {
                param.put("type","input");
            }
        } else if(dbtype.indexOf("NUMBER")>=0){
            if("NUMBER(1)".equals(dbtype)){
                if(oper.equals("bill_query")) {
                    param.put("config_type", "number");
                } else {
                    param.put("type","checkbox");
                }
                param.put("defaultValue","false");
            }
            else{
                if(oper.equals("bill_query")){
                    param.put("config_type", "number");
                } else {
                    param.put("type","inputNumber");
                }
                if(conFieldM.getFieldD(id).get("precision")==null){
                    param.put("precision","2");
                } else {
                    param.put("precision",conFieldM.getFieldD(id).get("precision"));
                }

            }
        } else if(dbtype.indexOf("TIMESTAMP")>=0){
            if(oper.equals("bill_query")){
                param.put("config_type", "dateRange");
            }
            else param.put("type","date");
        }
    }

    private void getFieldFini() throws Exception {
        if(param.get("id")==null){
            param.put("id", id);
        }
        if(param.get("key")==null){
            param.put("key", id);
        }
        if(param.get("field")==null){
            param.put("field", id);
        }
        if(param.get("label")==null){
            param.put("label", label);
        }
        param.put("placeholder", "请选择"+param.get("label"));
        if(notnull){
            param.put("required","true");
        }
        if(oper.equals("grid_oper")){
            if("MEMO".equals(id)){
                param.put("templateOptions.disabled","true");
            } else {
                param.put("templateOptions.disabled"," !(ctx.states == 'submit') ");
            }
        } else if(oper.equals("bill_oper")){
            if("IMP_ID".equals(id) || "STOP_ID".equals(id)  || "MEMO".equals(id)){
                param.put("templateOptions.disabled","true");
            } else {
                param.put("templateOptions.disabled"," !(formState.states == 'submit') ");
            }
        }
        if(oper.equals("bill_oper")){
            if("ID".equals(id)){
                param.put("type","span");
                param.put("templateOptions.disabled","!(ctx.states == 'submit')");
            }
        }
        if(oper.equals("bill_query")){
            param.put("divCol",12);
        }
        JSONObject infield=new JSONObject();
        infield.putAll(conFieldM.getFieldD(id));
        if(infield.size()>0){
            if(infield.get("event")!=null){
                JSONObject event=(JSONObject)infield.get("event");
                String type=event.getString("type");
                String callback=infield.getString("event_cdata");
                JSONObject d=new JSONObject();
                d.put("type", type);
                d.put("callback",callback);
                param.put("events", new JSONArray(d));
                infield.remove("event");
            } else if(infield.get("depend")!=null){
                JSONObject depend=JSON.toJSON(infield.get("depend"));
                String fields=depend.getString("fields");
                String method=infield.getString("depend_cdata");
                ArrayList<String> list=new ArrayList<String>();
                JSONObject d=new JSONObject();
                d.put("field", id);
                execSplitStr(fields,",", new SpiltStrCallback(){
                    @Override
                    public void exec(String id) throws Exception {
                        list.add(id);
                    }
                });
                d.put("fields", list);
                d.put("isTable", false);
                d.put("method", method);
                //param.put("onDepends", JSON.toJSONString(new JSONArray(d)));
                param.put("onDepends", d);
                if(depend.get("init")!=null){
                    param.put("init", depend.get("init"));
                }
                if(depend.get("api")!=null){
                    param.put("api", depend.get("api"));
                }
                infield.remove("depend");
            }
//            param.putAll(infield);
//            if(infield.get("templateOptions.disabled")!=null){
//                param.put("templateOptions.disabled",infield.get("templateOptions.disabled"));
//            }
//            if(infield.get("api")!=null){
//                param.put("api",infield.get("api"));
//            }
//            if(infield.get("init")!=null){
//                param.put("init", infield.get("init"));
//            }

        }

        param.put("key", id);
//        if(!djflag){
//            param.remove("multiple");
//        }
        if(oper.equals("bill_query")){
            ArrayList<String> olist=new ArrayList<String>();
            if(id.equals("EXE_CONDITION") || id.equals("EXE_DIMENSION") || id.equals("Z_ID")){
                if(esb){
                    olist.add("=");
                } else {
                    olist.add("EQ");
                }
            } else if("true".equals(param.get("multiple"))){
                if(esb){
                    olist.add("in");
                } else {
                    olist.add("IN");
                }
            } else {
                if("stop".equals(formType)){
                    olist.add("=");
                } else {
                    if(esb){
                        if(conFieldM.getField().equals(id)){
                            olist.add("like");
                        } else {
                            olist.add("in");
                        }
                    } else {
                        olist.add("LIKE");
                    }
                }
            }
            param.put("operators", olist);
            param.put("value","");
            param.put("inable",false);
            param.put("nullable", false);
            if(input!=null){
                if(input.get("operators")!=null) param.put("operators", input.get("operators"));
                if(input.get("value")!=null) param.put("value", input.get("value"));
                if(input.get("inable")!=null) param.put("inable", input.get("inable"));
                if(input.get("nullable")!=null) param.put("nullable", input.get("nullable"));
                if(input.get("required")!=null) param.put("required", input.get("required"));
                if(input.get("domain")!=null) param.put("domain", input.get("domain"));
                if(input.get("beforeQry")!=null){
                    JSONObject beforeQry= (JSONObject) input.get("beforeQry");
                    JSONObject in=new JSONObject();
                    in.put("sysField", rid);
                    in.put("sysKey", "{{value}}");
                    in.putAll(beforeQry);
                    param.put("domain",JSON.toJSONString(getDomain(in)));
                }
            }
        }
        param.remove("event_cdata");
        param.remove("event");
        param.remove("depend_cdata");
        param.remove("depend");
    }

    public void setEsb(boolean esb) {
        this.esb = esb;
    }

    public void setComment(String comment) throws Exception {
        if(comment==null){
            return;
        }
        this.comment = comment;
        label=getSpiltId(comment);
    }

    public void setNotnull(boolean notnull) {
        this.notnull = notnull;
    }

}
